/************************************************************************
 * @file StandardDockPanelManager.cpp
 * @author Ian Chen
 * @version 1.0
 *
 * @section LICENSE
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 * General Public License for more details at
 * http://www.gnu.org/licenses/lgpl.html
 *
 ************************************************************************/
#include <QHBoxLayout>
#include <QMenu>
#include <QAction>

#include <pluginui/manager/spi/StandardDockPanelManager.h>
#include <pluginui/manager/AbstractMenuManager.h>
#include <pluginui/manager/AbstractPanelContainer.h>

namespace antu
{
namespace plugin
{
namespace ui
{
StandardDockPanelManager::StandardDockPanelManager(AbstractMenuManager* pMenuManager, QMainWindow* pMainWindow)
    : AbstractPanelManager(),
      m_pMainWindow(pMainWindow),
      m_pMenuManager(pMenuManager)
{
}

void StandardDockPanelManager::finalize()
{
    auto dockIter = this->m_oDockWidgets.begin();
    auto dockEnd = this->m_oDockWidgets.end();
    auto containerIter = this->m_oPanels.begin();

    for (; dockIter != dockEnd; dockIter++, containerIter++)
    {
        (*containerIter)->finalize();
        if ((*dockIter)->widget() != (*containerIter)->containerWidget())
        {
            (*dockIter)->setWidget((*containerIter)->containerWidget());
        }
    }

    if (this->m_pMenuManager != nullptr)
    {
        auto iter = this->m_oPanels.begin();
        auto end = this->m_oPanels.end();

        auto dockIter = this->m_oDockWidgets.begin();

        bool restoreResult = false;
        QMenu* pWindowMenu = new QMenu(QObject::tr("&Window"));
        for (; iter != end; iter++, dockIter++)
        {
            AbstractPanelContainer* pContainer = *iter;

            if (pContainer->changeWindowTitleWithTab())
            {
                (*dockIter)->setWindowTitle(pContainer->containerWidget()->windowTitle());
                connect(pContainer, SIGNAL(tabChanged(QWidget*)), this, SLOT(tabPageChanged(QWidget*)));
            }

            if (pContainer->features() | QDockWidget::DockWidgetClosable)
            {
                QAction* pAction = (*dockIter)->toggleViewAction();
                pWindowMenu->addAction(pAction);

                pAction->activate(QAction::Trigger);
            }
            restoreResult = this->m_pMainWindow->restoreDockWidget(*dockIter);
        }

        QMenu* pMenu = this->m_pMenuManager->menu("toolMenu", tr("&Tools"));
        if (!pMenu->isEmpty())
            pMenu->addSeparator();
        pMenu->addMenu(pWindowMenu);
    }
}

void StandardDockPanelManager::createContainer(AbstractPanelContainer* pContainer,
                                               Qt::DockWidgetArea area,
                                               Qt::DockWidgetAreas allowedAreas,
                                               QDockWidget::DockWidgetFeatures features)
{
    QDockWidget* pContainerWidget = new QDockWidget(this->m_pMainWindow);

    pContainerWidget->setObjectName(pContainer->containerWidget()->objectName());
    pContainerWidget->setWidget(pContainer->containerWidget());
    pContainer->containerWidget()->setParent(pContainerWidget);
    pContainerWidget->setAllowedAreas(allowedAreas);
    pContainerWidget->setFeatures(features);
    pContainerWidget->setWindowTitle(pContainer->containerWidget()->windowTitle());
    this->m_oDockWidgets.push_back(pContainerWidget);

    QObject::connect(pContainerWidget, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), pContainer, SIGNAL(dockAreaChanged(Qt::DockWidgetArea)));
    QObject::connect(pContainerWidget, SIGNAL(topLevelChanged(bool)), pContainer, SIGNAL(floatingStateChanged(bool)));
    QObject::connect(pContainerWidget, SIGNAL(visibilityChanged(bool)), pContainer, SIGNAL(visibilityChanged(bool)));

    if (pContainer->isFloating())
    {
        this->m_pMainWindow->addDockWidget(area, pContainerWidget);
		pContainerWidget->setFloating(true);
    }
    else
	{
		this->m_pMainWindow->addDockWidget(area, pContainerWidget);
	}
}

void StandardDockPanelManager::tabPageChanged(QWidget *p)
{
    p->parentWidget()->setWindowTitle(p->windowTitle());
}

}
}
}

